#include "FeatureSetListModel.h"

#include "LeIpc2581/enumtranslator.h"
#include "LeIpc2581/Set.h"

#include <QDebug>
#include <QHash>
#include <QSet>

struct SetItem
{
    SetItem() {}
    explicit SetItem(const Ipc2581b::Set *set):
        set(set)
    {}

    const Ipc2581b::Set *set = nullptr;
};

class FeatureSetListModelPrivate
{
    Q_DISABLE_COPY(FeatureSetListModelPrivate)
    Q_DECLARE_PUBLIC(FeatureSetListModel)
    FeatureSetListModel * const q_ptr;

    explicit FeatureSetListModelPrivate(FeatureSetListModel *model):
        q_ptr(model)
    {}

    QList<SetItem> m_data;

    inline void clear()
    {
        m_data.clear();
    }
};

FeatureSetListModel::FeatureSetListModel(QObject *parent):
    QAbstractTableModel(parent),
    d_ptr(new FeatureSetListModelPrivate(this))
{
}

FeatureSetListModel::~FeatureSetListModel()
{

}

void FeatureSetListModel::addFeatureSet(const Ipc2581b::Set *set)
{
    Q_D(FeatureSetListModel);
    d->m_data.append(SetItem(set));
}

void FeatureSetListModel::clear()
{
    Q_D(FeatureSetListModel);

    beginResetModel();
    d->clear();
    endResetModel();
}

QVariant FeatureSetListModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation != Qt::Horizontal)
        return QVariant();

    if (role != Qt::DisplayRole)
        return QVariant();

    switch (section)
    {
        case NetColumn:
            return "Net";
        case PolarityColumn:
            return "Polarity";
        case PadUsageColumn:
            return "Pad usage";
        case TestPointColumn:
            return "Test point";
        case GeometryColumn:
            return "Geometry";
        case PlateColumn:
            return "Plated";
        case ComponentColumn:
            return "Component";
        default:
            return QVariant();
    }
}

int FeatureSetListModel::rowCount(const QModelIndex &parent) const
{
    Q_D(const FeatureSetListModel);

    if (parent.isValid())
        return 0;

    return d->m_data.count();
}

int FeatureSetListModel::columnCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;

    return ColumnCount;
}

QVariant FeatureSetListModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if (role != Qt::DisplayRole)
        return QVariant();

    if (index.row() < 0 || index.row() >= rowCount())
        return QVariant();

    Q_D(const FeatureSetListModel);
    const SetItem item = d->m_data.value(index.row());
    const Ipc2581b::Set *set = item.set;

    switch (index.column())
    {
        case NetColumn:
            if (set->netOptional.hasValue)
                return set->netOptional.value;
            return QVariant();
        case PolarityColumn:
            if (set->polarityOptional.hasValue)
                return Ipc2581b::EnumTranslator::polarityText(set->polarityOptional.value);
            return QVariant();
        case PadUsageColumn:
            if (set->padUsageOptional.hasValue)
                return Ipc2581b::EnumTranslator::padUsageText(set->padUsageOptional.value);
            return QVariant();
        case TestPointColumn:
            if (set->testPointOptional.hasValue)
                return set->testPointOptional.value;
            return QVariant();
        case GeometryColumn:
            if (set->geometryOptional.hasValue)
                return set->geometryOptional.value;
            return QVariant();
        case PlateColumn:
            if (set->plateOptional.hasValue)
                return set->plateOptional.value;
            return QVariant();
        case ComponentColumn:
            if (set->componentRefOptional.hasValue)
                return set->componentRefOptional.value;
            return QVariant();
        default:
            return QVariant();
    }
}
